/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package circlerectanglecollision;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;

/**
 *
 * @author danh.ngothanh
 */
public class MainPanel extends JPanel implements Runnable, MouseListener, MouseMotionListener{

    private Thread m_mainthread;
    private boolean is_running;
    private int m_rect_x, m_rect_y;
    private final int M_RECT_WIDTH = 500;
    private final int M_RECT_HEIGHT = 50;
    private int m_circle_center_x, m_circle_center_y;
    private final int M_CIRCLE_RADIUS = 100;
    private boolean is_holding_circle, is_holding_rect;
    private int m_rect_hold_offset_x, m_rect_hold_offset_y;
    private int m_circle_hold_offset_x, m_circle_hold_offset_y;
    Graphics2D g2d;//use to draw anti alias

    public MainPanel(){
        setSize(1200, 650);
    }

    public void Init(){
        m_rect_x = getWidth()/2;
        m_rect_y = getHeight()/2;
        m_circle_center_x = getWidth()/4;
        m_circle_center_y = getHeight()/4;
        is_holding_circle = false;
        is_holding_rect = false;
        addMouseListener(this);
        addMouseMotionListener(this);
        m_mainthread = new Thread(this);
        is_running = true;
        m_mainthread.start();
    }

     @Override
    public void paint(Graphics g){
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        g.drawRect(m_rect_x, m_rect_y, M_RECT_WIDTH, M_RECT_HEIGHT);
        g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.drawOval(m_circle_center_x - M_CIRCLE_RADIUS, m_circle_center_y - M_CIRCLE_RADIUS, M_CIRCLE_RADIUS*2, M_CIRCLE_RADIUS*2);
        if(CheckCollisionCircleRectangle(m_circle_center_x, m_circle_center_y, M_CIRCLE_RADIUS, m_rect_x, m_rect_y, M_RECT_WIDTH, M_RECT_HEIGHT))
            System.out.println("Hit");
        else
            System.out.println("");
    }

    public void run() {
        while(is_running){
            try{
                Thread.sleep(10);
            }catch(Exception e){
                e.printStackTrace();
            }
            repaint();
        }
    }

    private boolean CheckPointInRect(int px, int py, int rx, int ry, int rw, int rh){
		if(px >= rx && px <= (rx + rw) && py >= ry && py <= (ry + rh))
			return true;
		return false;
    }
    
    private boolean CheckPointInCircle(int point_x, int point_y, int circle_center_x, int circle_center_y, int radius){
            double distance = Math.sqrt(Math.pow((circle_center_x - point_x), 2) + Math.pow((circle_center_y - point_y), 2));
            if(distance <= radius)
                    return true;
            return false;
    }

    private boolean CheckCollisionCircleRectangle(int circle_center_x, int circle_center_y, int circle_radius, int rect_x, int rect_y, int rect_width, int rect_height){
        if(CheckPointInCircle(rect_x, rect_y, circle_center_x, circle_center_y, circle_radius)
         ||CheckPointInCircle(rect_x + rect_width, rect_y, circle_center_x, circle_center_y, circle_radius)
         ||CheckPointInCircle(rect_x, rect_y + rect_height, circle_center_x, circle_center_y, circle_radius)
         ||CheckPointInCircle(rect_x + rect_width, rect_y + rect_height, circle_center_x, circle_center_y, circle_radius)
          )
            return true;        
        if(((circle_center_x >= rect_x && circle_center_x <= rect_x + rect_width) && (circle_center_y - circle_radius <= rect_y + rect_height) && (circle_center_y > rect_y + rect_height))
         ||((circle_center_x >= rect_x && circle_center_x <= rect_x + rect_width) && (circle_center_y + circle_radius >= rect_y) && (circle_center_y < rect_y))
         ||((circle_center_y >= rect_y && circle_center_y <= rect_y + rect_height) && (circle_center_x - circle_radius <= rect_x + rect_width) && (circle_center_x > rect_x + rect_width))
         ||((circle_center_y >= rect_y && circle_center_y <= rect_y + rect_height) && (circle_center_x + circle_radius >= rect_x) && (circle_center_x < rect_x))
          )
            return true;       
        if(CheckPointInRect(circle_center_x - circle_radius, circle_center_y, rect_x, rect_y, rect_width, rect_height)
         ||CheckPointInRect(circle_center_x, circle_center_y - circle_radius, rect_x, rect_y, rect_width, rect_height)
         ||CheckPointInRect(circle_center_x + circle_radius, circle_center_y, rect_x, rect_y, rect_width, rect_height)
         ||CheckPointInRect(circle_center_x, circle_center_y + circle_radius, rect_x, rect_y, rect_width, rect_height)
          )
            return true;        
        return false;
    }

    public void mousePressed(MouseEvent e) {
        if(CheckPointInRect(e.getX(), e.getY(), m_rect_x, m_rect_y, M_RECT_WIDTH, M_RECT_HEIGHT)){
            m_rect_hold_offset_x = e.getX() - m_rect_x;
            m_rect_hold_offset_y = e.getY() - m_rect_y;
            is_holding_rect = true;
        }else
            is_holding_rect = false;
        if(CheckPointInCircle(e.getX(), e.getY(), m_circle_center_x, m_circle_center_y, M_CIRCLE_RADIUS)){
            m_circle_hold_offset_x = e.getX() - m_circle_center_x;
            m_circle_hold_offset_y = e.getY() - m_circle_center_y;
            is_holding_circle = true;
        }else{
            is_holding_circle = false;
        }
    }

    public void mouseDragged(MouseEvent e) {
        if(is_holding_rect){
            m_rect_x = e.getX() - m_rect_hold_offset_x;
            m_rect_y = e.getY() - m_rect_hold_offset_y;
        }
        if(is_holding_circle){
            m_circle_center_x = e.getX() - m_circle_hold_offset_x;
            m_circle_center_y = e.getY() - m_circle_hold_offset_y;
        }
    }
    
    public void mouseClicked(MouseEvent e) {

    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }
    
    public void mouseMoved(MouseEvent e) {

    }

}
